<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Vulkan Memory Allocator: VK_KHR_external_memory_win32</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Vulkan Memory Allocator
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.0 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search',false);
  $(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){ initResizable(false); });
/* @license-end */
</script>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="index.html">Vulkan Memory Allocator</a></li>  </ul>
</div>
</div><!-- top -->
<div id="doc-content">
<div><div class="header">
  <div class="headertitle"><div class="title">VK_KHR_external_memory_win32</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 <code>HANDLE</code> of a <code>VkDeviceMemory</code> block, to be able to reference the memory on other Vulkan logical devices or instances, in multiple processes, and/or in multiple APIs. VMA offers support for it.</p>
<h1><a class="anchor" id="vk_khr_external_memory_win32_initialization"></a>
Initialization</h1>
<p>1) Make sure the extension is defined in the code by including following header before including VMA:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;vulkan/vulkan_win32.h&gt;</span></div>
</div><!-- fragment --><p>2) Check if "VK_KHR_external_memory_win32" is available among device extensions. Enable it when creating the <code>VkDevice</code> object.</p>
<p>3) Enable the usage of this extension in VMA by setting flag <a class="el" href="group__group__init.html#gga4f87c9100d154a65a4ad495f7763cf7ca4897d1181a186e327f4dadd680ad00ac">VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT</a> when calling <a class="el" href="group__group__init.html#ga200692051ddb34240248234f5f4c17bb" title="Creates VmaAllocator object.">vmaCreateAllocator()</a>.</p>
<p>4) Make sure that VMA has access to the <code>vkGetMemoryWin32HandleKHR</code> function by either enabling <code>VMA_DYNAMIC_VULKAN_FUNCTIONS</code> macro or setting <a class="el" href="struct_vma_vulkan_functions.html#af45d10a2b47971f4cf5bcacf1d331f86">VmaVulkanFunctions::vkGetMemoryWin32HandleKHR</a> explicitly. For more information, see <a class="el" href="quick_start.html#quick_start_initialization_importing_vulkan_functions">Importing Vulkan functions</a>.</p>
<h1><a class="anchor" id="vk_khr_external_memory_win32_preparations"></a>
Preparations</h1>
<p>You can find example usage among tests, in file "Tests.cpp", function <code>TestWin32Handles()</code>.</p>
<p>To use the extenion, buffers need to be created with <code>VkExternalMemoryBufferCreateInfoKHR</code> attached to their <code>pNext</code> chain, and memory allocations need to be made with <code>VkExportMemoryAllocateInfoKHR</code> attached to their <code>pNext</code> chain. To make use of them, you need to use <a class="el" href="custom_memory_pools.html">Custom memory pools</a>. Example:</p>
<div class="fragment"><div class="line"><span class="comment">// Define an example buffer and allocation parameters.</span></div>
<div class="line">VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {</div>
<div class="line">    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,</div>
<div class="line">    <span class="keyword">nullptr</span>,</div>
<div class="line">    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT</div>
<div class="line">};</div>
<div class="line">VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div>
<div class="line">exampleBufCreateInfo.size = 0x10000; <span class="comment">// Doesn&#39;t matter here.</span></div>
<div class="line">exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div>
<div class="line">exampleBufCreateInfo.pNext = &amp;externalMemBufCreateInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> exampleAllocCreateInfo = {};</div>
<div class="line">exampleAllocCreateInfo.<a class="code hl_variable" href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <a class="code hl_enumvalue" href="group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e">VMA_MEMORY_USAGE_AUTO</a>;</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Find memory type index to use for the custom pool.</span></div>
<div class="line">uint32_t memTypeIndex;</div>
<div class="line">VkResult res = <a class="code hl_function" href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a>(g_Allocator,</div>
<div class="line">    &amp;exampleBufCreateInfo, &amp;exampleAllocCreateInfo, &amp;memTypeIndex);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// Create a custom pool.</span></div>
<div class="line"><span class="keyword">constexpr</span> <span class="keyword">static</span> VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {</div>
<div class="line">    VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,</div>
<div class="line">    <span class="keyword">nullptr</span>,</div>
<div class="line">    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT</div>
<div class="line">};</div>
<div class="line"><a class="code hl_struct" href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a> poolCreateInfo = {};</div>
<div class="line">poolCreateInfo.<a class="code hl_variable" href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">memoryTypeIndex</a> = memTypeIndex;</div>
<div class="line">poolCreateInfo.<a class="code hl_variable" href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41">pMemoryAllocateNext</a> = (<span class="keywordtype">void</span>*)&amp;exportMemAllocInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_pool.html">VmaPool</a> pool;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a>(g_Allocator, &amp;poolCreateInfo, &amp;pool);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, don&#39;t forget to destroy it!</span></div>
<div class="line"><a class="code hl_function" href="group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a>(g_Allocator, pool);</div>
<div class="ttc" id="agroup__group__alloc_html_ga5485779c8f1948238fc4e92232fa65e1"><div class="ttname"><a href="group__group__alloc.html#ga5485779c8f1948238fc4e92232fa65e1">vmaDestroyPool</a></div><div class="ttdeci">void vmaDestroyPool(VmaAllocator allocator, VmaPool pool)</div><div class="ttdoc">Destroys VmaPool object and frees Vulkan device memory.</div></div>
<div class="ttc" id="agroup__group__alloc_html_ga5c8770ded7c59c8caac6de0c2cb00b50"><div class="ttname"><a href="group__group__alloc.html#ga5c8770ded7c59c8caac6de0c2cb00b50">vmaCreatePool</a></div><div class="ttdeci">VkResult vmaCreatePool(VmaAllocator allocator, const VmaPoolCreateInfo *pCreateInfo, VmaPool *pPool)</div><div class="ttdoc">Allocates Vulkan device memory and creates VmaPool object.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gae790ab9ffaf7667fb8f62523e6897888"><div class="ttname"><a href="group__group__alloc.html#gae790ab9ffaf7667fb8f62523e6897888">vmaFindMemoryTypeIndexForBufferInfo</a></div><div class="ttdeci">VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, uint32_t *pMemoryTypeIndex)</div><div class="ttdoc">Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.</div></div>
<div class="ttc" id="agroup__group__alloc_html_ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e"><div class="ttname"><a href="group__group__alloc.html#ggaa5846affa1e9da3800e3e78fae2305cca27cde9026a84d34d525777baa41fce6e">VMA_MEMORY_USAGE_AUTO</a></div><div class="ttdeci">@ VMA_MEMORY_USAGE_AUTO</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:550</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html"><div class="ttname"><a href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a></div><div class="ttdoc">Parameters of new VmaAllocation.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1291</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html_accb8b06b1f677d858cb9af20705fa910"><div class="ttname"><a href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">VmaAllocationCreateInfo::usage</a></div><div class="ttdeci">VmaMemoryUsage usage</div><div class="ttdoc">Intended usage of memory.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1299</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html"><div class="ttname"><a href="struct_vma_pool_create_info.html">VmaPoolCreateInfo</a></div><div class="ttdoc">Describes parameter of created VmaPool.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1342</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html_a596fa76b685d3f1f688f84a709a5b319"><div class="ttname"><a href="struct_vma_pool_create_info.html#a596fa76b685d3f1f688f84a709a5b319">VmaPoolCreateInfo::memoryTypeIndex</a></div><div class="ttdeci">uint32_t memoryTypeIndex</div><div class="ttdoc">Vulkan memory type index to allocate this pool from.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1345</div></div>
<div class="ttc" id="astruct_vma_pool_create_info_html_ab6f2e52c47bfe1f4b44920b8bfc27b41"><div class="ttname"><a href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41">VmaPoolCreateInfo::pMemoryAllocateNext</a></div><div class="ttdeci">void *VkMemoryAllocateInfo pMemoryAllocateNext</div><div class="ttdoc">Additional pNext chain to be attached to VkMemoryAllocateInfo used for every allocation made by this ...</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1394</div></div>
<div class="ttc" id="astruct_vma_pool_html"><div class="ttname"><a href="struct_vma_pool.html">VmaPool</a></div><div class="ttdoc">Represents custom memory pool.</div></div>
</div><!-- fragment --><p>Note that the structure passed as <a class="el" href="struct_vma_pool_create_info.html#ab6f2e52c47bfe1f4b44920b8bfc27b41" title="Additional pNext chain to be attached to VkMemoryAllocateInfo used for every allocation made by this ...">VmaPoolCreateInfo::pMemoryAllocateNext</a> must remain alive and unchanged for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block. No copy is made internally. This is why variable <code>exportMemAllocInfo</code> is defined as <code>static</code>.</p>
<h1><a class="anchor" id="vk_khr_external_memory_win32_memory_allocation"></a>
Memory allocation</h1>
<p>Finally, you can create a buffer with an allocation out of the custom pool. The buffer should use same flags as the sample buffer used to find the memory type. It should also specify <code>VkExternalMemoryBufferCreateInfoKHR</code> in its <code>pNext</code> chain.</p>
<div class="fragment"><div class="line">VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {</div>
<div class="line">    VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,</div>
<div class="line">    <span class="keyword">nullptr</span>,</div>
<div class="line">    VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT</div>
<div class="line">};</div>
<div class="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div>
<div class="line">bufCreateInfo.size = <span class="comment">// Your desired buffer size.</span></div>
<div class="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;</div>
<div class="line">bufCreateInfo.pNext = &amp;externalMemBufCreateInfo;</div>
<div class="line"> </div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div>
<div class="line">allocCreateInfo.<a class="code hl_variable" href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">pool</a> = pool;  <span class="comment">// It is enough to set this one member.</span></div>
<div class="line"> </div>
<div class="line">VkBuffer buf;</div>
<div class="line"><a class="code hl_struct" href="struct_vma_allocation.html">VmaAllocation</a> alloc;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(g_Allocator, &amp;bufCreateInfo, &amp;allocCreateInfo, &amp;buf, &amp;alloc, <span class="keyword">nullptr</span>);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, don&#39;t forget to destroy it!</span></div>
<div class="line"><a class="code hl_function" href="group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a>(g_Allocator, buf, alloc);</div>
<div class="ttc" id="agroup__group__alloc_html_ga0d9f4e4ba5bf9aab1f1c746387753d77"><div class="ttname"><a href="group__group__alloc.html#ga0d9f4e4ba5bf9aab1f1c746387753d77">vmaDestroyBuffer</a></div><div class="ttdeci">void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation)</div><div class="ttdoc">Destroys Vulkan buffer and frees allocated memory.</div></div>
<div class="ttc" id="agroup__group__alloc_html_gac72ee55598617e8eecca384e746bab51"><div class="ttname"><a href="group__group__alloc.html#gac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a></div><div class="ttdeci">VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)</div><div class="ttdoc">Creates a new VkBuffer, allocates and binds memory for it.</div></div>
<div class="ttc" id="astruct_vma_allocation_create_info_html_a6272c0555cfd1fe28bff1afeb6190150"><div class="ttname"><a href="struct_vma_allocation_create_info.html#a6272c0555cfd1fe28bff1afeb6190150">VmaAllocationCreateInfo::pool</a></div><div class="ttdeci">VmaPool pool</div><div class="ttdoc">Pool that this allocation should be created in.</div><div class="ttdef"><b>Definition</b> vk_mem_alloc.h:1323</div></div>
<div class="ttc" id="astruct_vma_allocation_html"><div class="ttname"><a href="struct_vma_allocation.html">VmaAllocation</a></div><div class="ttdoc">Represents single memory allocation.</div></div>
</div><!-- fragment --><p>If you need each allocation to have its own device memory block and start at offset 0, you can still do by using <a class="el" href="group__group__alloc.html#ggad9889c10c798b040d59c92f257cae597a3fc311d855c2ff53f1090ef5c722b38f" title="Set this flag if the allocation should have its own memory block.">VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT</a> flag. It works also with custom pools.</p>
<h1><a class="anchor" id="vk_khr_external_memory_win32_exporting_win32_handle"></a>
Exporting Win32 handle</h1>
<p>After the allocation is created, you can acquire a Win32 <code>HANDLE</code> to the <code>VkDeviceMemory</code> block it belongs to. VMA function <a class="el" href="group__group__alloc.html#ga8d327b7458d8cf426b84b5efba9bb9bf" title="Given an allocation, returns Win32 handle that may be imported by other processes or APIs.">vmaGetMemoryWin32Handle()</a> is a replacement of the Vulkan function <code>vkGetMemoryWin32HandleKHR</code>.</p>
<div class="fragment"><div class="line">HANDLE handle;</div>
<div class="line">res = <a class="code hl_function" href="group__group__alloc.html#ga8d327b7458d8cf426b84b5efba9bb9bf">vmaGetMemoryWin32Handle</a>(g_Allocator, alloc, <span class="keyword">nullptr</span>, &amp;handle);</div>
<div class="line"><span class="comment">// Check res...</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// YOUR OTHER CODE COMES HERE....</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// At the end, you must close the handle.</span></div>
<div class="line">CloseHandle(handle);</div>
<div class="ttc" id="agroup__group__alloc_html_ga8d327b7458d8cf426b84b5efba9bb9bf"><div class="ttname"><a href="group__group__alloc.html#ga8d327b7458d8cf426b84b5efba9bb9bf">vmaGetMemoryWin32Handle</a></div><div class="ttdeci">VkResult vmaGetMemoryWin32Handle(VmaAllocator allocator, VmaAllocation allocation, HANDLE hTargetProcess, HANDLE *pHandle)</div><div class="ttdoc">Given an allocation, returns Win32 handle that may be imported by other processes or APIs.</div></div>
</div><!-- fragment --><p>Documentation of the VK_KHR_external_memory_win32 extension states that:</p>
<blockquote class="doxtable">
<p>&zwj;If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType. </p>
</blockquote>
<p>This is ensured automatically inside VMA. The library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed. Every time you call <a class="el" href="group__group__alloc.html#ga8d327b7458d8cf426b84b5efba9bb9bf" title="Given an allocation, returns Win32 handle that may be imported by other processes or APIs.">vmaGetMemoryWin32Handle()</a>, VMA calls <code>DuplicateHandle</code> and returns a new handle that you need to close.</p>
<p>For further information, please check documentation of the <a class="el" href="group__group__alloc.html#ga8d327b7458d8cf426b84b5efba9bb9bf" title="Given an allocation, returns Win32 handle that may be imported by other processes or APIs.">vmaGetMemoryWin32Handle()</a> function. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.13.0
</small></address>
</div><!-- doc-content -->
</body>
</html>
